/*
 * AplAtividade.java
 * 
 * Projeto: Kruskal - SRAC
 * LEDS - Laboratório de Engenharia e Desenvolvimento de Software
 * IFES - Instituto Federal do Espírito Santo - Campus Serra.
 */
package srac.controleatividades.cgt;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import srac.controleatividades.cdp.*;
import srac.controleatividades.cgd.AlunoDAOJPA;
import srac.controleatividades.cgd.AtividadeComplementarDAOJPA;
import srac.controleatividades.cgd.EtapaDAOJPA;
import srac.controleeventos.cdp.Certificado;
import srac.controleeventos.cdp.Evento;
import srac.controleeventos.cdp.Participante;
import srac.controleeventos.cdp.TipoEvento;
import srac.controleeventos.cgt.AplControleEvento;
import util.utilitarioExceptions.SracException;
import util.utilitarioPersistencia.DAO;
import util.utilitarioPersistencia.DAOFactory;

public class AplAtividade {

    private DAO apDaoAtividade = DAOFactory.obterDAO(AtividadeComplementar.class);
    private DAO apDaoEtapa = DAOFactory.obterDAO(Etapa.class);
    private DAO apDaoAluno = DAOFactory.obterDAO(Aluno.class);
    private DAO apDaoRelatorioFinal = DAOFactory.obterDAO(RelatorioFinal.class);

    private AplAtividade() {
    }
    private static AplAtividade instance = null;

    public static AplAtividade getInstance() {
        if (instance == null) {
            instance = new AplAtividade();
        }
        return instance;
    }
    
    /**
     * Inclui uma nova Atividade Complementar
     * @param args
     * @throws Exception
     * @return A atividade icluida ou Null caso haja algum erro
     */
    
public AtividadeComplementar incluirAtividadeComplementar(ArrayList<Object> args) throws Exception {
        AtividadeComplementar atividade = new AtividadeComplementar();

        atividade.setTipoAtividade((TipoAtividade) args.get(0));
        atividade.setDescricao((String) args.get(1));
        atividade.setCreditosRequeridos((Integer) args.get(2));
        atividade.setArquivo((byte[]) args.get(3));
        atividade.setObservacao((String) args.get(4));
        atividade.setAluno((Aluno) args.get(5));
        atividade.setStatusAtividadeComplementar(StatusAtividadeComplementar.REGISTRADA);
        atividade.setCreditosObtidos((Integer) args.get(2));

        return (AtividadeComplementar) apDaoAtividade.salvar(atividade);

    }
    
    
    /**
     * Altera uma Atividade Complementar
     * @param args
     * @throws Exception
     * @return A nova Atividade Complementar modificada ou Null caso haja algum erro
     */

    public AtividadeComplementar alterarAtividadeComplementar(AtividadeComplementar atividade) throws Exception {
        Etapa etapa = this.obterEtapaAtual();
        if(atividade.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.IRREGULAR) || atividade.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.REJEITADA))
        {
            if(!atividade.getEtapa().equals(etapa))
            {
                atividade.setStatusAtividadeComplementar(StatusAtividadeComplementar.REGISTRADA);
            } 
        }
        return (AtividadeComplementar) apDaoAtividade.salvar(atividade);
    }
    
    /**
     * Apaga uma Atividade Complementar
     * @param atividadeComplementar
     * @throws Exception
     * @return Verdadeiro caso foi possivel Apagar a Atividade Complementar ou Falso caso contrário
     */

    public boolean apagarAtividadeComplementar(AtividadeComplementar atividade) throws Exception {
        //validacao
        if (atividade.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.REGISTRADA)) {
            //exclusao
            apDaoAtividade.excluir(atividade);
            return true;
        }

        return false;
    }
    
    /**
     * Obtem todas as Atividades Complementares cadastradas
     * @throws Exception
     * @return Uma lista de Atividades Complementares ou Null caso haja algum erro
     */

    public List<AtividadeComplementar> obterAtividadesComplementares() throws Exception {
        return (List<AtividadeComplementar>) apDaoAtividade.obter(AtividadeComplementar.class);
    }
    
    /**
     * Obtem todas as Atividades Complementares cadastradas da Etapa 'e'
     * @throws Exception
     * @return Uma lista de Atividades Complementares ou Null caso haja algum erro
     */

    public List<AtividadeComplementar> obterAtividadesComplementares(Etapa e) throws Exception {
        return ((AtividadeComplementarDAOJPA) apDaoAtividade).obterAtividadesComplementares(e);
    }
    
    /**
     * Obter Atividades Complementares pelo TipoAtividade
     * @param t
     * @throws Exception
     * @return Uma lista de Atividades ou Null caso haja algum erro
     */

    public List<AtividadeComplementar> obterAtividadesComplementares(TipoAtividade t) throws Exception {
        return ((AtividadeComplementarDAOJPA) apDaoAtividade).obterAtividadesComplementares(t);
    }
    
    /**
     * Obter as Atividades Complementares do Aluno
     * @param a
     * @throws Exception
     * @return Uma lista de Atividades ou Null caso haja algum erro
     */

    public List<AtividadeComplementar> obterAtividadesComplementares(Aluno a) throws Exception {
        return ((AtividadeComplementarDAOJPA) apDaoAtividade).obterAtividadesComplementares(a);
    }
    
    /**
     * Obtem as Atividade Complementares com o StatusAtividadeComplementar
     * @param a
     * @param s
     * @return Uma lista de Atividades ou Null caso haja algum erro
     * @throws Exception 
     */
    
    public List<AtividadeComplementar> obterAtividadesComplementares(Aluno a, StatusAtividadeComplementar s) throws Exception {
        return ((AtividadeComplementarDAOJPA) apDaoAtividade).obterAtividadesComplementares(a,s);
    }
    
    /**
     * Obter as Atividades Complementares do Aluno 'a' na Etapa 'e'
     * @param a
     * @param e
     * @throws Exception
     * @return Uma lista de Atividades ou Null caso haja algum erro
     */
    
     public List<AtividadeComplementar> obterAtividadesComplementares(Aluno a, Etapa e) throws Exception {
        return ((AtividadeComplementarDAOJPA) apDaoAtividade).obterAtividadesComplementares(a,e);
    }
    
     /**
     * Obtem as Atividades Complementares do TipoAtividades com o Status 's'
     * @param t
     * @param s
     * @throws Exception
     * @return Uma lista de Atividades ou Null caso haja algum erro
     */

    public List<AtividadeComplementar> obterAtividadesComplementares(TipoAtividade t, StatusAtividadeComplementar s) throws Exception {
        return ((AtividadeComplementarDAOJPA) apDaoAtividade).obterAtividadesComplementares(t, s);
    }
    
    /**
     * Modifica o Status do Aluno
     * @param aluno
     * @param statusSubmissao
     * @throws Exception 
     */

    public void mudarStatus(Aluno aluno, StatusSubmissao statusSubmissao) throws Exception {
        aluno.setStatusSubmissao(statusSubmissao);
        apDaoAluno.salvar(aluno);
    }
    
    /**
     * Obtem as Atividades Complementares pelo TipoAtividade para validação (Em análise, aceitas, rejeitadas, aceitas modificadas)
     * @param obj
     * @throws Exception 
     * @return return Uma lista de Atividades
     */

    public List<AtividadeComplementar> obterAtividadesComplementaresValidacao(TipoAtividade obj) {
        return ((AtividadeComplementarDAOJPA) apDaoAtividade).obterAtividadesComplementaresValidacao(obj);
    }

    /**
     * Verifica se os atributos Tipo de Atividade e Créditos Obtidos de um Aluno são diferentes dos que foram também passados
     * por parâmetro.
     * @param obj
     * @param atributosNovos
     * @throws Exception
     * @return Verdadeiro se houver diferença entre algum atributo. Caso contrário retorna falso.
     */
    public boolean atividadeModificada(AtividadeComplementar obj, List<Object> atributosNovos) {
        TipoAtividade tipo = (TipoAtividade) atributosNovos.get(0);
        Integer creditosObtidos = (Integer) atributosNovos.get(1);
        
        if (tipo != obj.getTipoAtividade() || creditosObtidos != obj.getCreditosRequeridos()) {
            return true;
        }
        
        return false;
    }
    
    /**
     * Inclui um nova Etapa
     * @param args
     * @throws Exception
     * @return A etapa incluida ou Null caso haja algum erro
     */

    public Etapa incluirEtapa(ArrayList<Object> args) throws Exception {
        Etapa etapa = new Etapa();

        etapa.setDescricao((String) args.get(0));
        etapa.setDataInicioSubmissao((Calendar) args.get(1));
        etapa.setDataFimSubmissao((Calendar) args.get(2));
        etapa.setDataFimVerificacao((Calendar) args.get(3));
        etapa.setDataFimValidacao((Calendar) args.get(4));
        etapa.setStatusEtapa(StatusEtapa.NAO_INICIADA);
        
        
        
           //PARA TESTE
        Calendar c = etapa.getDataInicioSubmissao();
        Date d = new Date(c.getTime().getYear(), c.getTime().getMonth(), c.getTime().getDate(), 16, 56, 0);
        Reminder r1 = new Reminder(etapa,d,1);
        
        c = etapa.getDataInicioSubmissao();
        d = new Date(c.getTime().getYear(), c.getTime().getMonth(), c.getTime().getDate(), 16, 57, 0);
        Reminder r2 = new Reminder(etapa,d,2);
        
        c = etapa.getDataInicioSubmissao();
        d = new Date(c.getTime().getYear(), c.getTime().getMonth(), c.getTime().getDate(), 16, 58, 0);
        Reminder r3 = new Reminder(etapa,d,3);
        
        c = etapa.getDataInicioSubmissao();
        d = new Date(c.getTime().getYear(), c.getTime().getMonth(), c.getTime().getDate(), 17, 01, 0);
        Reminder r4 = new Reminder(etapa,d,4);

        

//        Calendar c = etapa.getDataInicioSubmissao();
//        Date d = new Date(c.getTime().getYear(), c.getTime().getMonth(), c.getTime().getDate(), 0, 0, 0);
//        Reminder r1 = new Reminder(etapa,d,1);
//  
//        c = etapa.getDataFimSubmissao();
//        d = new Date(c.getTime().getYear(), c.getTime().getMonth(), c.getTime().getDate(), 23, 59, 0);
//        Reminder r2 = new Reminder(etapa,d,2);
//        
//        c = etapa.getDataFimVerificacao();
//        d = new Date(c.getTime().getYear(), c.getTime().getMonth(), c.getTime().getDate(), 23, 59, 0);
//        Reminder r3 = new Reminder(etapa,d,3);
//        
//        c = etapa.getDataFimValidacao();
//        d = new Date(c.getTime().getYear(), c.getTime().getMonth(), c.getTime().getDate(), 23, 59, 0);
//        Reminder r4 = new Reminder(etapa,d,4);

   
        apDaoEtapa.salvar(etapa);

        return etapa;
    }

    /**
     * Altera uma Etapa cadastrada
     * @param args
     * @throws Exception
     * @return A Etapa modificada ou Null caso haj algum erro
     */
    public Etapa alterarEtapa(Etapa etapa) throws Exception {
        return (Etapa) apDaoEtapa.salvar(etapa);
    }
    
    /**
     * Apaga uma Etapa
     * @param Etapa
     * @throws Exception
     * @return Verdadeiro caso foi possível apagar a Etapa ou Falso caso contrário
     */

    public boolean apagarEtapa(Etapa etapa) throws Exception {
        //validacao
        if (!this.obterAtividadesComplementares(etapa).isEmpty()) {
            return false;
        }

        //exclusao
        apDaoEtapa.excluir(etapa);
        return true;
    }
    
    /**
     * Obtem todas Etapas cadastradas
     * @return Uma lista de Etapas
     * @throws Exception 
     */

    public List<Etapa> obterEtapas() throws Exception {
        return (List<Etapa>) apDaoEtapa.obter(Etapa.class);
    }
    
    /**
     * Obtem todas Etapas cadastradas diferentes da Etapa passada por paramêtro
     * @return Uma lista de Etapas
     * @throws Exception 
     */

    public List<Etapa> obterEtapas(Etapa etapa) throws Exception {
        return ((EtapaDAOJPA) apDaoEtapa).obterEtapas(etapa);
    }
    
    /**
     * Obtem a Etapa Atual
     * @return Uma lista de Etapas
     * @throws Exception 
     */
    
    public List<Etapa> obterEtapa() throws Exception {
        return ((EtapaDAOJPA) apDaoEtapa).obterEtapaAtual();
    }
    
    /**
     * Obtem a Próxima Etapa a ser iniciada
     * @return Uma lista de Etapas
     * @throws Exception 
     */
    
    public List<Etapa> obterEtapaProx() throws Exception {
        return ((EtapaDAOJPA) apDaoEtapa).obterProximaEtapa();
    }

    /**
     * Busca a etapa atual do sistema
     * @return A etapa cuja data de inicio é posterior a data atual do sistema
     * @throws Exception 
     */
    
    public Etapa obterEtapaAtual() throws Exception {
        List<Etapa> etapa = obterEtapa();
        if (etapa.isEmpty()) {
            return null;
        }
        return etapa.get(0);
    }
    
    /**
     * Busca a etapa mais próxima da data atual que ainda não foi iniciada
     * @return A próxima etapa a ser iniciada
     * @throws Exception 
     */
    public Etapa obterProximaEtapa() throws Exception {
        List<Etapa> etapa = obterEtapaProx();
        if (etapa.isEmpty()) {
            return null;
            
        }
        else if(etapa.size()==1)
        {
            return etapa.get(0);
        }
        Etapa aux = null;
        for (int i = 0; i < etapa.size()-1; i++) {
            if(etapa.get(i).getDataInicioSubmissao().before(etapa.get(i+1).getDataInicioSubmissao()))
            {
                aux = etapa.get(i);
            }
            else
            {
                aux = etapa.get(i+1);
            }
        }
        return aux;
        
    }
    
    /**
     * Verifica se as datas estão no mesmo dia
     * @param c1
     * @param c2
     * @return Verdadeiro se as datas estão no mesmo dia ou Falso se estão em dias diferentes
     */
    
    public boolean comparaDatas(Calendar c1, Calendar c2)
    {
        int dia1 = c1.getTime().getDay();
        int mes1 = c1.getTime().getMonth();
        int ano1 = c1.getTime().getYear();
        int dia2 = c2.getTime().getDay();
        int mes2 = c2.getTime().getMonth();
        int ano2 = c2.getTime().getYear();
        if((dia1 == dia2) && (mes1 == mes2) && (ano1 == ano2)) return true;
        return false;
    }
    
    /**
     * Altera o Status da Etapa
     * @param e
     * @param s
     * @throws Exception 
     */
    
    public void alteraStatusEtapa(Etapa e, StatusEtapa s) throws Exception{
        e.setStatusEtapa(s);
        apDaoEtapa.salvar(e);
    }
    
    /**
     * Altera o status da Atividade Complementar para o que foi passado como parametro.
     * @param a Atividade Complementar
     * @param status Status para o qual se deseja alterar a Atividade
     * @throws Exception 
     */
    public void registrarResultadoConferencia(AtividadeComplementar a, StatusAtividadeComplementar status) throws Exception {
        a.setStatusAtividadeComplementar(status);
        this.alterarAtividadeComplementar(a);
    }
    
    /**
     * Registra o resultado do que a secretaria conferriu, verifica quantos pontos o aluno obteve com as atividades conferidas,
     * se for >=15 modifica o status para Atividades Conferidas, senão modifica para Atividades Conferidas Inapto
     * @param list
     * @param a
     * @return Verdadeiro se o aluno ficou com atividades conferidas ou Falso caso contrário
     * @throws Exception 
     */
    
    public boolean registrarResultado(List<AtividadeComplementar> list, Aluno a) throws Exception {
        int soma = 0;
        for (AtividadeComplementar atividadeComplementar : list) {
            if (atividadeComplementar.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.CONFERIDA)) {
                soma += atividadeComplementar.getCreditosRequeridos();
            }
        }
        if (soma >= 15) {
            a.setStatusSubmissao(StatusSubmissao.ATIVIDADES_CONFERIDAS);
            apDaoAluno.salvar(a);
            return true;
        }
        a.setStatusSubmissao(StatusSubmissao.ATIVIDADES_CONFERIDAS_INAPTO);
        apDaoAluno.salvar(a);
        return false;
    }

   /**
    * Obtem todos alunos que submeteram atividades
    * @return Uma lista de Alunos
    */

    public List<Aluno> obterAlunosComAtividadesSubmetidas() {
        return ((AlunoDAOJPA) apDaoAluno).obterAlunosComAtividadesSubmetidas();
    }
    
    /**
    * Obtem todos alunos cadastrados
    * @return Uma lista de Alunos
    */
    
    public List<Aluno> obterAlunos() throws Exception {
        return (List<Aluno>) apDaoAluno.obter(Aluno.class);
    }
    
    /**
    * Obtem todos alunos que estão com as atividades conferidas
    * @return Uma lista de Alunos
    */
    
    public List<Aluno> obterAlunosValidacao() throws Exception {
        return ((AlunoDAOJPA) apDaoAluno).obterAlunosValidacao();
    }

    /**
     * Verifica se a etapa não está no intervalo de outra etapa cadastrada
     * @param inicioEtapa
     * @param fimEtapa
     * @return Verdadeiro se ela não está no intervalo de nenhuma outra etapa  ou Falso se ela está
     * @throws Exception 
     */
    public boolean validarEtapa(Calendar inicioEtapa, Calendar fimEtapa) throws  Exception {
        List<Etapa> etapas = this.obterEtapas();
        boolean b = true;
        for (Etapa e : etapas) {
            if (inicioEtapa.after(e.getDataFimValidacao())) {
                b = true;
            } else if (fimEtapa.before(e.getDataInicioSubmissao())) {
                b = true;
            } else {
                b = false;
            }
        }
        return b;
    }
    
    /**
     * Verifica se alguma etapa diferente da passada por paramêtro está no intervalo de outra etapa cadastrada
     * @param etapa
     * @param inicioEtapa
     * @param fimEtapa
     * @return Verdadeiro se ela não está no intervalo de nenhuma outra etapa  ou Falso se ela está
     * @throws Exception 
     */

    public boolean validarEtapa(Etapa etapa, Calendar inicioEtapa, Calendar fimEtapa) throws  Exception {
        List<Etapa> etapas = this.obterEtapas(etapa);
        boolean b = true;
        for (Etapa e : etapas) {
            if (inicioEtapa.after(e.getDataFimValidacao())) {
                b = true;
            } else if (fimEtapa.before(e.getDataInicioSubmissao())) {
                b = true;
            } else {
                b = false;
            }
        }
        return b;
    }


    /**
     * Verifica se as atividades podem ser submetidas
     * @param selecionados
     * @return 0 se a soma de todas as é >=15 e em alguma categoria o aluno teve mais de 10 pontos,
     * 1 se a soma de todas as é >=15 e em nenhuma categoria o aluno teve mais de 10 pontos,
     * 2 se a soma de todas as é menor do que 15 e em nenhuma categoria o aluno teve mais de 10 pontos,
     * 3 se a soma de todas as é menor do que 15 e em alguma categoria o aluno teve mais de 10 pontos.
     */

    public int verificarSubmissao(ArrayList<AtividadeComplementar> selecionados){
        boolean b;
        int soma = 0;
        List<ClassificadorAtividades> classificadorAtividades;
        if(!selecionados.get(0).getAluno().getStatusSubmissao().equals(StatusSubmissao.EM_ANALISE))
        {
            
            classificadorAtividades = obterTotaldeClassificadores(selecionados);
            b = false;
            //Percorrendo lista de classificadores (categorias) e verificando a quantidade de créditos em cada um
            for (ClassificadorAtividades c : classificadorAtividades) {
                //Se a quantidade de créditos for maior que 10, somente 10 é adicionado à soma
                if(c.getQuantidade() > 10)
                {
                    soma += 10;
                    b = true;
                }
                //Senão a quantidade real de créditos é adicionado
                else
                {
                    soma += c.getQuantidade();
                }
            }

            if (soma >= 15 && b) {
                return 0;
            }
            else if(soma >= 15 && !b)
            {
                return 1;
            }
            else if(soma<15 && !b)    
            {
                return 2;
            }
            else
            {
                return 3;
            }
        }
        else
        {
            return 1;
        }
    }
    
    /**
     * Modifica o status das atividades para submetidas e adiciona a etapa nelas
     * @param selecionadas
     * @throws Exception 
     */

    public void submeterAtividades(ArrayList<AtividadeComplementar> selecionadas) throws Exception {
        Etapa etapa = this.obterEtapaAtual();
        for (AtividadeComplementar a : selecionadas) {
            a.setStatusAtividadeComplementar(StatusAtividadeComplementar.SUBMETIDA);         
            a.setEtapa(etapa);
            this.alterarAtividadeComplementar(a);
        }

    }
    
    /**
     * Modifica o status da atividade
     * @param a
     * @param status
     * @throws Exception 
     */

    public void registrarResultadoValidar(AtividadeComplementar a, StatusAtividadeComplementar status) throws Exception {
        a.setStatusAtividadeComplementar(status);
        this.alterarAtividadeComplementar(a);
    }

    /**
     * Dos alunos que estão com status de Atividades Conferidas, modifica-se o status das atividades conferidas para em análise, modifica-se a submetidas para registradas.
     * @throws Exception 
     */
    public void encerrarEtapaConferencia() throws  Exception
    {
        List<Aluno> alunos;
        List<AtividadeComplementar> atividades;
        alunos = this.obterAlunos();
        for (Aluno aluno : alunos) {
            atividades = this.obterAtividadesComplementares(aluno);
            if(aluno.getStatusSubmissao().equals(StatusSubmissao.ATIVIDADES_CONFERIDAS))
            {
                for (AtividadeComplementar a : atividades) {
                    if(a.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.CONFERIDA))
                    {
                        a.setStatusAtividadeComplementar(StatusAtividadeComplementar.EM_ANALISE);
                    }
                    else if(a.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.SUBMETIDA))
                    {
                        a.setStatusAtividadeComplementar(StatusAtividadeComplementar.REGISTRADA);
                        a.setEtapa(null);
                    }
                    this.alterarAtividadeComplementar(a);
                }
            }
            else
            {
                for (AtividadeComplementar a : atividades) {
                    if(a.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.CONFERIDA) || a.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.SUBMETIDA))
                    a.setStatusAtividadeComplementar(StatusAtividadeComplementar.REGISTRADA);
                    this.alterarAtividadeComplementar(a);
                }
                aluno.setStatusSubmissao(StatusSubmissao.ATIVIDADES_PENDENTES);
                apDaoAluno.salvar(aluno);
            }
        }       
    }
    
    /**
     * Modifica o status dos alunos que conseguiram 15 pontos para atividades aceitas, e dos que não conseguiram para atividades pendentes
     * @throws Exception 
     */
    public void encerrarEtapaValidacao() throws Exception
    {
        List<Aluno> alunos;
        List<AtividadeComplementar> atividades;
        int soma;
        RelatorioFinal relatorio = new RelatorioFinal();
        
        List<Aluno> relatorioAluno = new ArrayList<Aluno>();
        List<Integer> relatorioSoma = new ArrayList<Integer>();
        Etapa relatorioEtapa;
        
        alunos = this.obterAlunosValidacao();
        for (Aluno aluno : alunos) {
            atividades = this.obterAtividadesComplementares(aluno);
            soma =0;
            for (AtividadeComplementar a : atividades) {
                if(a.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.ACEITA) || a.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.ACEITA_MODIFICADA))
                {
                   soma+= a.getCreditosObtidos(); 
                }
                if(a.getStatusAtividadeComplementar().equals(StatusAtividadeComplementar.EM_ANALISE))
                {
                    a.setStatusAtividadeComplementar(StatusAtividadeComplementar.REGISTRADA);
                    apDaoAtividade.salvar(a);
                }   
            
            }
            if(soma>=15)
            {
                aluno.setStatusSubmissao(StatusSubmissao.ATIVIDADES_ACEITAS);              
            }
            else
            {
                aluno.setStatusSubmissao(StatusSubmissao.ATIVIDADES_PENDENTES);
            }
            relatorioAluno.add(aluno);
            relatorioSoma.add(soma);
            relatorioEtapa = this.obterEtapaAtual();
            
            relatorio.setArquivo(FinalToPdf.gerarPdf(relatorioAluno, relatorioSoma, relatorioEtapa));
            relatorio.setEtapa(relatorioEtapa);
            
            apDaoRelatorioFinal.salvar(relatorio);
            
            apDaoAluno.salvar(aluno);
        } 
    }

    /**
     * Verifica a etapa
     * @param obj
     * @return 0 se ela já foi finalizada, 1 se nenhuma atividades está vinculada com ela, se não for nenhuma das primeiras retorna 2
     */

    public int verificarEtapa(Etapa obj) {
        if(obj.getStatusEtapa().equals(StatusEtapa.FINALIZADA)) return 0;
        List<AtividadeComplementar> l = ((AtividadeComplementarDAOJPA) apDaoAtividade).obterAtividadesComplementares(obj);
        if(l.isEmpty()) return 1;
        return 2;
    }

    /**
     * Obter todos Relatórios Finais cadastrados
     * @return Uma lista de Relatórios Finais
     * @throws Exception 
     */

    public List<RelatorioFinal> obterRelatorioFinal() throws Exception {
        return apDaoRelatorioFinal.obter(RelatorioFinal.class);
    }
    
    /**
     * Separa as atividades em classificadores (Categoria, Creditos Requeridos, Total de atividades nessa categoria)
     * @param atividades
     * @return Uma lista de Classificadores
     */

    public List<ClassificadorAtividades> obterTotaldeClassificadores(List<AtividadeComplementar> atividades) {
        List<ClassificadorAtividades> classificadorAtividades = new ArrayList<ClassificadorAtividades>();
        boolean b;
        //Percorrendo lista de atividades
        for (AtividadeComplementar a : atividades) {
            //Percorrendo lista de classificadores (categorias)
            b = false;
            for (ClassificadorAtividades c : classificadorAtividades) {
                //Se a categoria já existir na lista, o valor dos créditos é incrementado
                if(a.getTipoAtividade().getCategoria().equals(c.getCategoria()))
                {
                    c.setQuantidade(c.getQuantidade()+a.getCreditosRequeridos());
                    c.setAtividades(c.getAtividades()+1);
                    b = true;
                }
            }
            //Se a categoria não foi encontrada, é adicionado um novo classificador
            if(!b) {
                classificadorAtividades.add(new ClassificadorAtividades(a.getTipoAtividade().getCategoria(), a.getCreditosRequeridos(), 1));
            }
        }
        return classificadorAtividades;
    }

    /**
     * Obtem o total de potos por categoria
     * @param obj
     * @param s
     * @return Uma lista de classificadores
     */
    public List<ClassificadorAtividades> obterTotaldePontosCategoria(Aluno obj, StatusAtividadeComplementar s) {
        List<AtividadeComplementar> l = ((AtividadeComplementarDAOJPA) apDaoAtividade).obterAtividadesComplementares(obj, s);
        return obterTotaldeClassificadores(l);
    }
    
    /**
     * Formata uma data para exibição na interface
     * @param data
     * @return Um String com a data formatada
     */

    public String formatarData(Calendar data) {
        Integer dia, mes, ano;
        String resultado;
        dia = data.get(Calendar.DATE);
        mes = data.get(Calendar.MONTH) +1;
        ano = data.get(Calendar.YEAR);
        resultado = dia.toString()+"/";
        if(mes<10)
        {
            resultado+="0"+mes.toString()+"/";
        }
        else
        {
            resultado+=mes.toString()+"/";
        }
        resultado+=ano.toString();
        return resultado;
        
    }
    
    /**
     * Se o dia atual está depois de uma data
     * @param data
     * @return Verdadeiro se está ou Falso senão está
     */
    
    public boolean passou(Calendar data){
        Calendar c = Calendar.getInstance();
        if(comparaDatas(c, data)) return false;
        else if (data.before(c)) {
            return true;
        }
        return false;
        
    }
    
    /**
     * Verifica se existe algum relatório final cadastrado
     * @return Verdadeiro se existe ou Falso se n existe
     * @throws Exception 
     */

    public boolean verificarExistenciaRelatorio() throws Exception {
        List<RelatorioFinal> r = apDaoRelatorioFinal.obter(RelatorioFinal.class);
        if(r!=null)
        {
            if(r.isEmpty())
            {
                return false;
            }
            return true;
        }
        return false;
    }
    
    
    public AtividadeComplementar incluirAtividadeEvento(Evento e, Aluno a) {
        
        Participante part = null;
        Certificado c;
        for (Participante p : a.getParticipacoes()) {
            if(p.getEvento().equals(e))
            {
                part = p;
                break;
            }
        }
        if(part!=null)
        {
            try
            {
                c = AplControleEvento.getInstance().obterCertificados(part).get(0);
                ArrayList<Object> l = new ArrayList<Object>();
                
                l.add(e.getTipo().getTipoAtividade());
                l.add(e.getNome());
                l.add(e.getTipo().getTipoAtividade().getCreditos());
                l.add(c.getArquivo());
                l.add("Evento do IFES");
                l.add(a);
                a.getParticipacoes().remove(part);
                AplCadastroInterno.getInstance().alterarAluno(a);
                return incluirAtividadeComplementar(l);
            }
            catch(Exception ex)
            {
                System.out.println(ex);
                return null;
            }
        }
        return null;
    }
    
    
    
}
